package com.zplus.managers.petservices.controllers;

import com.zplus.managers.petservices.entities.Pet;
import com.zplus.managers.petservices.services.PetService;
import com.zplus.managers.petservices.services.PetState;
import com.zplus.managers.petservices.utils.Message;
import com.zplus.managers.petservices.utils.Page;
import com.zplus.managers.petservices.utils.PagingFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping(value = "/pet", method = RequestMethod.GET)
public class PetController
{
    @Autowired
    private PetService petService;

    private PagingFactory pagingFactory;


    /**
     * return all pets of given species
     * @param species given species
     * @return message with first page, emtpy page with code 100 otherwise
     */
    @RequestMapping(value = "/getpetbyspeci", method = RequestMethod.GET)
    Message getPetsBySpeci(@RequestParam("species")String species, @RequestParam("pageSize")int pageSize)
    {
        Message msg = new Message();
        // check pageSize validation
        if (pageSize <= 0)
        {
            msg.fail("invalid pageSize, positive number are accepted.");
            return msg;
        }
        // query data with species
        List<Pet> petsBySpeci = petService.getPetsBySpeci(species);
        // check if data is empty
        if(petsBySpeci == null)
        {
            msg.fail();
            return msg;
        }
        // load init paging system
        pagingFactory = new PagingFactory(petsBySpeci, pageSize);
        // load msg
        Page page = pagingFactory.nextPage();
        msg.loadPage(page);
        //return msg
        return msg;
    }

    /**
     * get pets with given type
     * @param pageSize num of items that a page can hold
     * @param state pet state accept: 'unadopt', 'adopting', 'adopted', empty for all pets
     * @return message content with page 1 of result
     */
    @RequestMapping(value = "/getpets", method = RequestMethod.GET)
    Message getAllPets(@RequestParam("pageSize") int pageSize, @RequestParam("state")String state)
    {
        Message msg = new Message();
        // check page size validation
        if(pageSize <= 0)
        {
            msg.fail("invalid pageSize");
            return msg;
        }
        // get data using service
        List<Pet> pets;
        switch(state)
        {
            case "unadopt":
                pets = petService.queryPets(PetState.UNADOPTED);
                break;
            case "adopting":
                pets = petService.queryPets(PetState.IN_ADOPT);
                break;
            case "adopted":
                pets = petService.queryPets(PetState.ADOPTED);
                break;
            default:
                pets = petService.queryPets(PetState.ALL);
        }
        // check data not empty
        if(pets == null)
        {
            msg.fail("no pet found");
            return msg;
        }
        // load init paging system
        pagingFactory = new PagingFactory(pets, pageSize);
        Page page = pagingFactory.nextPage();
        // load msg
        msg.loadPage(page);
        // return msg;
        return msg;
    }


    @RequestMapping(value = "/getpage", method = RequestMethod.GET)
    Message getPage(@RequestParam("index")int index)
    {
        Message msg = new Message();
        // check index & paging system validation
        if(pagingFactory == null || index <= 0 || (pagingFactory != null && index > pagingFactory.getTotalPages()))
        {
            msg.fail();
            return msg;
        }
        // get target page
        Page page = pagingFactory.getPage(index);
        msg.loadPage(page);
        return msg;
    }
    /**
     * get pet object by id
     * @param id the given id
     * @return message with a Map contains the pet object and code 200 if success, code 100 with
     * empty content otherwise.
     */
    @RequestMapping("/getpetbyid")

    Message getPetById(@RequestParam("pid")int id)
    {
        Message msg = new Message();
        Pet pet = petService.queryPetById(id);
        if (pet == null)
        {
            msg.fail();
            return msg;
        }

        List<Pet> plst = new ArrayList<>();
        plst.add(pet);
        msg.load(plst);
        msg.ok();
        return msg;
    }

    /**
     * restore a new pet by the given pet object
     * @param pet stores the infos of a new pet
     * @return Message, only operation results, contents remain empty
     */
    @RequestMapping(value = "/addpet", method = RequestMethod.POST)
    Message newPet(@RequestBody Pet pet)
    {
        Message msg = new Message();
        if( petService.newPet(pet))
            msg.ok();
        else
            msg.fail();
        return msg;
    }

    /**
     * give a pet object, set pet info as the object stores, identified by id
     * @param pet the pet object
     * @return Message, only operation reuslts, contents remain empty
     */
    @RequestMapping(value = "/altpet", method = RequestMethod.POST)
    Message altPet(@RequestBody Pet pet)
    {
        Message msg = new Message();
        if(petService.updatePetInfo(pet))
            msg.ok();
        else
            msg.fail();
        return msg;
    }

    /**
     * delete pet by the given id
     * @param id the id of pet to be deleted
     * @return Message, only operation result, contents remain empty
     */
    @RequestMapping(value = "/delpet", method = RequestMethod.GET)
    Message delPet(@RequestParam("petid") int id)
    {
       Message msg = new Message();
        Pet pet = new Pet();
        pet.setId(id);
        if(petService.deletePet(pet))
            msg.ok();
        else
            msg.fail();
       return msg;
    }

}
